/**
 * @file clock.c
 */

#include "clock.h"
#include "LPC17xx.h"


/**
 *
 */
void clock_init(void)
{

    /* Enable GPIO power. */
    SC->PCONP |= PCONP_PCGPIO;

    /* Disable TPIU. */
    PINCON->PINSEL10 = 0;

    /* Disable PLL, disconnected. */
    SC->PLL0CON = 0;
    SC->PLL0FEED = PLLFEED_FEED1;
    SC->PLL0FEED = PLLFEED_FEED2;

    /* Enable main OSC. */
    SC->SCS |= OSC_ENABLE;

    /* wait for main oscillator to be ready */
    while (!(SC->SCS & OSC_READY));

    /* select main OSC, 12MHz, as the PLL clock source. */
    SC->CLKSRCSEL = CLOCK_SOURCE_EXTERNAL;

    /* set multiplier and divider */
    SC->PLL0CFG = PLL_M_VALUE|PLL_N_VALUE;
    SC->PLL0FEED = PLLFEED_FEED1;
    SC->PLL0FEED = PLLFEED_FEED2;

    /* Enable PLL, disconnected. */
    SC->PLL0CON = PLL_ENABLED;
    SC->PLL0FEED = PLLFEED_FEED1;
    SC->PLL0FEED = PLLFEED_FEED2;

    /* Set clock divider. */
    SC->CCLKCFG = CLK_DIVIDER_VALUE;

    /* Configure flash accelerator. */
    SC->FLASHCFG = FLASH_TIMING_VALUE;

    /* Check lock bit status. */
    while (!(SC->PLL0STAT & PLLSTAT_PLOCK));

    /* Enable and connect. */
    SC->PLL0CON |= PLL_CONNECT;
    SC->PLL0FEED = PLLFEED_FEED1;
    SC->PLL0FEED = PLLFEED_FEED2;

    /* wait for PLL being enabled and connected */
    while (!(SC->PLL0STAT & PLLSTAT_PLLC));

    /* Disable PLL, disconnected. */
    SC->PLL1CON = PLL_DISABLED;
    SC->PLL1FEED = PLLFEED_FEED1;
    SC->PLL1FEED = PLLFEED_FEED2;

    SC->PLL1CFG = PLL1_CFG_VALUE;
    SC->PLL1FEED = PLLFEED_FEED1;
    SC->PLL1FEED = PLLFEED_FEED2;

    /* Enable PLL, disconnected. */
    SC->PLL1CON = PLL_ENABLED;
    SC->PLL1FEED = PLLFEED_FEED1;
    SC->PLL1FEED = PLLFEED_FEED2;

    /* wait for PLL being enabled and connected */
    while (!(SC->PLL1STAT & PLL1_LOCKED));

    /* Enable and connect. */
    SC->PLL1CON |= PLL_CONNECT;
    SC->PLL1FEED = PLLFEED_FEED1;
    SC->PLL1FEED = PLLFEED_FEED2;

    /* wait for PLL being enabled and connected */
    while (!(SC->PLL1STAT & PLL1_STAT));

    /*  Setup the peripheral bus here see LPC1768 errata sheet */
    SC->PCLKSEL0 = PCLK1_VALUE;
    SC->PCLKSEL1 = PCLK2_VALUE;

}
